package com.yhy.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.yhy.autoconfig.templates.OssTemplate;
import com.yhy.domain.UserInfo;
import com.yhy.domain.mongo.Comment;
import com.yhy.domain.mongo.FollowUser;
import com.yhy.domain.mongo.Video;
import com.yhy.domain.vo.CommentVo;
import com.yhy.domain.vo.PageResult;
import com.yhy.domain.vo.VideoVo;
import com.yhy.dubbo.api.UserInfoApi;
import com.yhy.dubbo.api.mongo.CommentApi;
import com.yhy.dubbo.api.mongo.VideoApi;
import com.yhy.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;


import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class SmallVideosService {

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Reference
    private VideoApi videoApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private CommentApi commentApi;


    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    /**
     * 上传视频
     * @param videoThumbnail
     * @param videoFile
     * @return
     * @throws IOException
     */
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity uploadVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //1.首先判断图片是否为空
        String imgUrl = null;
        if(!videoThumbnail.isEmpty()){
            imgUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        }
//        2.上传视频文件到 FDFS
//        2.1 获取所需参数
        String fileName = videoFile.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
//        2.2 获取videoUrl
        StorePath store = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), suffix, null);
        String videoUrl = webServer.getWebServerUrl() + store.getFullPath();
//        3.封装video
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(imgUrl);
        video.setVideoUrl(videoUrl);
        video.setText("炉石传说");
//        4.调用api上传视频
        videoApi.save(video);
        return ResponseEntity.ok(null);
    }

    /**
     * 查找小视频列表
     * @param page
     * @param pagesize
     * @return
     */
    @Cacheable(value ="videoList",key = "#page+'_'+#pagesize")
    public PageResult queryVideoList(Integer page, Integer pagesize) {

        Long userId = UserHolder.getUserId();

        //0.小视频大数据推荐系统 先从redis中获取视频推荐数据 如果没有则查询数据库
//        PageResult pageResult = queryRecommend(page, pagesize);
//        if(pageResult == null){
//            pageResult = videoApi.queryVideoList(page,pagesize);
//        }
        //1.查找video表 返回包含分页参数和List<Video>的pageResult
        PageResult pageResult = videoApi.queryVideoList(page, pagesize);

        //2.将pageResult里的List<Video>替换成List<VideoVo> 满足页面需要的参数
        List<Video> items = (List<Video>) pageResult.getItems();
        List<VideoVo> list = new ArrayList<>();
        for (Video item : items) {
            UserInfo userInfo = userInfoApi.findById(item.getUserId());
            VideoVo videoVo = VideoVo.init(userInfo, item);
            if(redisTemplate.hasKey("like_video_"+userId+"_"+item.getId().toHexString())){
                videoVo.setHasLiked(1);
            }
            list.add(videoVo);
        }
        //2.1替换List
        pageResult.setItems(list);
        return pageResult;
    }

    //从redis中查询推荐数据
    private PageResult queryRecommend(Integer page, Integer pagesize) {
        //1、拼接Redis中的key
        String key = "QUANZI_VIDEO_RECOMMEND_"+UserHolder.getUserId();
        //2、从reids中获取推荐数据（2161,2198,2202,2039,2145,2128,2074,2191,2137,2088，1,2,3,4,5,6,,7,8,9） ，表示动态的pid
        String values = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(values)) {
            //redis中不存在，没有推荐数据
            return null;
        }
        String vidstr [] = values.split(",");
        //3、计算分页条数
        int counts = vidstr.length; // 总条数     9
        int start = (page - 1) * pagesize ;//起始条数  0
        List<Video> list = new ArrayList<>();
        if(start < counts) {  //起始条数 < 总条数
            int end = start + pagesize - 1 ; //最后一条的索引    9
            if(end > counts) {
                end = counts;
            }
            for (int i=start ; i<end; i++ ) {
                Long vid = Long.valueOf(vidstr[i]);
                //根据pid查询动态对象
                Video video = videoApi.findByVid(vid);
                list.add(video);
            }
        }

        //4、构建返回值
        return new PageResult(page,pagesize,counts,list);
    }

    /**
     * 关注视频作者
     * @param followUserId
     * @return
     */
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity userFocus(Long followUserId) {

        FollowUser followUser = new FollowUser();
        followUser.setUserId(UserHolder.getUserId());
        followUser.setFollowUserId(followUserId);

        videoApi.saveFollowUser(followUser);
        //为了获取关注状态 将操作记录放入redis
        redisTemplate.opsForValue().set("followUser"+UserHolder.getUserId()+"_"+followUserId,"0");

        return ResponseEntity.ok(null);
    }

    /**
     * 取消关注视频作者
     * @param followUserId
     * @return
     */
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity userUnFocus(Long followUserId) {

        FollowUser followUser = new FollowUser();
        followUser.setUserId(UserHolder.getUserId());
        followUser.setFollowUserId(followUserId);

        videoApi.deleteFollowUser(followUser);
        //删除关注的操作记录
        redisTemplate.delete("followUser"+UserHolder.getUserId()+"_"+followUserId);

        return ResponseEntity.ok(null);
    }

    //视频点赞
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity likeVideo(String videoId) {

        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setId(ObjectId.get());
        comment.setUserId(userId);
        comment.setCommentType(5);
        comment.setPublishId(new ObjectId(videoId));
        Integer count = commentApi.save(comment);

        redisTemplate.opsForValue().set("like_video_"+userId+"_"+videoId,"0");
        return ResponseEntity.ok(count);
    }

    //视频点赞-取消
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity dislikeVideo(String videoId) {

        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCommentType(5);
        comment.setPublishId(new ObjectId(videoId));
        Integer count = commentApi.delete(comment);

        redisTemplate.delete("like_video_"+userId+"_"+videoId);
        return ResponseEntity.ok(count);
    }
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity comments(Integer page,Integer pagesize,String videoId) {
        PageResult pageResult = commentApi.queryVideoCommentList(page, pagesize, videoId);

        List<Comment> commentList = (List<Comment>) pageResult.getItems();

        List<CommentVo> list = new ArrayList<>();
        for (Comment comment : commentList) {
            UserInfo userInfo = userInfoApi.findById(comment.getUserId());
            CommentVo vo = CommentVo.init(userInfo, comment);
            list.add(vo);
        }

        pageResult.setItems(list);
        return ResponseEntity.ok(pageResult);
    }
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity commitComments(String videoId, String content) {
//        1.确定当前userId和要提交的类型6
        Long userId = UserHolder.getUserId();

        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setPublishId(new ObjectId(videoId));
        comment.setContent(content);
        comment.setCreated(System.currentTimeMillis());
        comment.setCommentType(6);

        commentApi.save(comment);
        return ResponseEntity.ok(null);
    }
}
